/*
 * Copyright (C) 2022 KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <https://www.gnu.org/licenses/>.
 */

#include "database.h"
#include "utils.h"
#include <QSqlQuery>
#include <QSqlError>
#include <QDate>
#include <QFile>
#include <QRect>
#include <QStandardPaths>
#include <QDebug>
#include <DatabaseSql.h>
#include "types.h"

DataBase::DataBase(const QString &databasePath, QObject *parent) : QObject(parent)
{
    if (!QSqlDatabase::drivers().contains("QSQLITE")) {
        qWarning() << "Unable to load database, this demo needs the SQLITE3 driver ! ! !";
    }

    // 创建一个数据库连接，指定数据库驱动
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(databasePath);
}

DataBase::~DataBase()
{
    db.close();
}

bool DataBase::openDatabase()
{
    if (!db.open()) {
        qDebug() << db.lastError().text();
        return false;
    }
    if (!checkTables()) {
        return false;
    }
    qDebug() << "DataBase Tables: " << db.tables();
    return true;
}

void DataBase::createItemsData()
{
    QString desktopName("widgetPlugin1");
    QString sql = SELECT_ITEMLIST_BY_DESKTOPNAME;
    QSqlQuery sqlQuery;
    sqlQuery.prepare(sql);
    sqlQuery.bindValue(":desktopName", desktopName);
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << sqlQuery.lastError();
        return;
    }
    while(sqlQuery.next()) {
        quint32 id = 0;
        id = sqlQuery.value(0).toUInt();
        if(id > 0) {
            return;
        }
    }
//    addItem(0, QLatin1String("taskbar"), "taskbar", "null", 3, {1, 1});
}

bool DataBase::isTableExist(const QString &tableName)
{
    if (db.tables().contains(tableName, Qt::CaseInsensitive)) {
        return true;
    } else {
        return false;
    }
}

void DataBase::checkSetsTableFields()
{
    QString tableName = "sets";
    QString columnName = "name";

    QSqlQuery query;
    query.exec("PRAGMA table_info(" + tableName + ")");

    QStringList fieldNames;
    while (query.next()) {
        QString name = query.value(columnName).toString();
        fieldNames.push_back(name);
    }

    for (int i=0; i<SETS_TABLE_FIELDS_COUNT; ++i) {
        if (fieldNames.contains(setsTableFields[i])) {
            continue;
        }
        if (!query.exec(QString("ALTER TABLE sets ADD COLUMN %1 varchar").arg(setsTableFields[i]))) {
            qWarning() << __func__ << query.lastError().text();
            continue;
        }
    }
}

bool DataBase::addItemToItemList(const QMap<QString, QVariant> &itemDetails)
{
    QSqlQuery sqlQuery;
    if (!sqlQuery.prepare(QLatin1String(INSERT_ITEMLIST))) {
        qWarning() << __func__ << sqlQuery.lastError().text();
        return false;
    }
    sqlQuery.addBindValue(itemDetails.value("itemId").toInt());
    sqlQuery.addBindValue(itemDetails.value("desktopName").toString());
    sqlQuery.addBindValue(itemDetails.value("name").toString());
    sqlQuery.addBindValue(itemDetails.value("iconName").toString());
    sqlQuery.addBindValue(itemDetails.value("type").toInt());
    sqlQuery.addBindValue(itemDetails.value("placeholder").toString());
    sqlQuery.addBindValue(itemDetails.value("categories").toString());
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << sqlQuery.lastError();
        return false;
    }
    return true;
}

bool DataBase::addItemToSets(const QMap<QString, QVariant> &itemDetails)
{
    QSqlQuery sqlQuery;
    if (!sqlQuery.prepare(QLatin1String(INSERT_SETS))) {
        qWarning() << __func__ << sqlQuery.lastError().text();
        return false;
    }
    sqlQuery.addBindValue(itemDetails.value("setId").toInt());
    sqlQuery.addBindValue(itemDetails.value("sequence").toString());
    sqlQuery.addBindValue(itemDetails.value("titleEditable").toBool());
    sqlQuery.addBindValue(itemDetails.value("containerEditable").toBool());
    sqlQuery.addBindValue(itemDetails.value("containerCategory").toString());
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << sqlQuery.lastError();
        return false;
    }
    return true;
}

DataBase::ItemDetail DataBase::queryItemDetailsFromItemListTable(const QSqlQuery &query) const
{
    QMap<QString, QVariant> tmpMap;
    ItemDetail item;
    for (int i=0; i<ITEMLIST_TABLE_FIELDS_COUNT; ++i) {
        tmpMap[itemListTableFields[i]] = query.value(itemListTableFields[i]);
    }
    item.itemId = tmpMap.value(VAR_TO_FIELD(itemId)).toInt();
    item.type = tmpMap.value(VAR_TO_FIELD(type)).toInt();
    item.desktopName = tmpMap.value(VAR_TO_FIELD(desktopName)).toString();
    item.name = tmpMap.value(VAR_TO_FIELD(name)).toString();
    item.iconName = tmpMap.value(VAR_TO_FIELD(iconName)).toString();
    item.placeholder = tmpMap.value(VAR_TO_FIELD(placeholder)).toString();
    item.categories = tmpMap.value(VAR_TO_FIELD(categories)).toString();
    return item;
}

std::tuple<int, QString> DataBase::queryItemDetailsFromPageTable(const QSqlQuery &query) const
{
    QMap<QString, QVariant> tmpMap;
    for (int i=0; i<PAGE_TABLE_FIELDS_COUNT; ++i) {
        tmpMap[pageTableFields[i]] = query.value(pageTableFields[i]);
    }
    int pageId = tmpMap.value(VAR_TO_FIELD(pageId)).toInt();
    QString sequence = tmpMap.value(VAR_TO_FIELD(sequence)).toString();
    return std::make_tuple(pageId, sequence);
}

std::tuple<int, QString> DataBase::queryItemDetailsFromSetsTable(const QSqlQuery &query) const
{
    QMap<QString, QVariant> tmpMap;
    for (int i=0; i<SETS_TABLE_FIELDS_COUNT; ++i) {
        tmpMap[setsTableFields[i]] = query.value(setsTableFields[i]);
    }
    int setId = tmpMap.value(VAR_TO_FIELD(setId)).toInt();
    QString sequence = tmpMap.value(VAR_TO_FIELD(sequence)).toString();
    return std::make_tuple(setId, sequence);
}

std::tuple<bool, bool, QString> DataBase::queryContainerPropertyFromSetsTable(const int containerId) const
{
    QSqlQuery sqlQuery;
    sqlQuery.prepare(SELECT_SETS_BY_SETID);
    sqlQuery.bindValue(":setId", containerId);
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << sqlQuery.lastError();
        return std::make_tuple(false, false, QString());
    }
    while (sqlQuery.next()) {
        bool titleEditable = sqlQuery.value(VAR_TO_FIELD(titleEditable)).toBool();
        bool containerEditable = sqlQuery.value(VAR_TO_FIELD(containerEditable)).toBool();
        QString containerCategory = sqlQuery.value(VAR_TO_FIELD(containerCategory)).toString();
        return std::make_tuple(titleEditable, containerEditable, containerCategory);
    }
    return std::make_tuple(false, false, QString());
}

bool DataBase::updateHomeScreenPageTable(int pageId, const QList<int> &sequence, const char *sql)
{
    QString itemSequence = UKUI::fromQListUIntToString(sequence);
    QSqlQuery sqlQuery;
    if (!sqlQuery.prepare(QLatin1String(sql))) {
        qWarning() << "Update home screen page table failed." << sqlQuery.lastError();
        return false;
    }
    sqlQuery.addBindValue(itemSequence);
    sqlQuery.addBindValue(pageId);
    if (!sqlQuery.exec()) {
        qWarning() << "Update home screen page table failed." << sqlQuery.lastError();
        return false;
    }
    return true;
}

UKUI::ItemMap DataBase::queryAllItemData() const
{
    UKUI::ItemMap itemList;
    QSqlQuery sqlQuery;
    if (!sqlQuery.exec(SELECT_ITEMLIST)) {
        qWarning() << __func__ << sqlQuery.lastError();
        return itemList;
    }

    while (sqlQuery.next()) {
        ItemDetail item = queryItemDetailsFromItemListTable(sqlQuery);
        QStringList placeholderStrList = item.placeholder.split(',');
        if (placeholderStrList.count() != 2) {
            qWarning() << "Item placeholder error from itemlist table."
                       << item.itemId << item.name << item.placeholder;
            continue;
        }
        QList<int> placeholderList = { placeholderStrList.constFirst().toInt(),
                                       placeholderStrList.constLast().toInt() };

        QStringList categoryStrList = item.categories.split(',');
        QList<int> categoryList;
        for (auto &category : qAsConst(categoryStrList)) {
            categoryList.append(category.toInt());
        }

        switch (item.type) {
        case DataBase::Icon:
            itemList[item.itemId] = new UKUI::IconItem(item.desktopName, item.name,
                                                       item.itemId, item.iconName, categoryList);
            break;
        case DataBase::Group: {
            QString friendlyName = item.name;
            // translate the 'name'
            if (friendlyName.startsWith(DEFAULT_GROUP_NAME_PREFIX)) {
                QString sourceName = friendlyName.remove(0, sizeof(CUSTOM_GROUP_NAME_PREFIX)-1);
                friendlyName = UKUI::translatedName(sourceName);
                if (friendlyName.isEmpty()) {
                    friendlyName = item.name.remove(0, sizeof(CUSTOM_GROUP_NAME_PREFIX)-1);
                }
            } else if (item.name.startsWith(CUSTOM_GROUP_NAME_PREFIX)){
                friendlyName.remove(0, sizeof(CUSTOM_GROUP_NAME_PREFIX)-1);
            }
            itemList[item.itemId] = new UKUI::GroupItem(friendlyName.isEmpty() ? item.name : friendlyName, item.itemId);
            break;
        }

        case DataBase::Container: {
            bool titleEditable, containerEditable;
            QString containerCategory;
            std::tie(titleEditable, containerEditable, containerCategory) =
                    queryContainerPropertyFromSetsTable(item.itemId);
            itemList[item.itemId] = new UKUI::ContainerItem(item.name, item.itemId, placeholderList,
                    titleEditable, containerEditable, containerCategory);
            break;
        }
        case DataBase::Widget:
            itemList[item.itemId] = new UKUI::Widget(item.desktopName, item.name, item.itemId, placeholderList);
            break;
        default:
            break;
        }
    }

    return itemList;
}

QMap<int, QList<QList<int> > > DataBase::queryAllItemIdsInSet()
{
    QMap<int, QList<QList<int>>> allSets;
    QSqlQuery sqlQuery;

    if (!sqlQuery.exec(SELECT_SETS)) {
        qWarning() << __func__ << sqlQuery.lastError();
        return allSets;
    }

    while(sqlQuery.next()) {
        int setId;
        QString ids;
        std::tie(setId, ids) = queryItemDetailsFromSetsTable(sqlQuery);
        QStringList sequence = ids.split(';');

        for (int i = 0; i < sequence.size(); ++i) {
            QStringList setPageItem = sequence.at(i).split(",");
            QList<int> itemList;
            for (int j = 0; j < setPageItem.size(); ++j) {
                if(queryItemIdFromList(setPageItem.at(j).toUInt()) &&
                        setPageItem.at(j).toUInt() != 0) {
                    itemList.append(setPageItem.at(j).toUInt());
                }
            }
            allSets[setId].append(itemList);
        }
    }

    return allSets;
}

QMap<int, QList<int> > DataBase::queryAllItemIdsInHomeScreen()
{
    QMap<int, QList<int>> itemsIdInHomeScreen;
    QSqlQuery sqlQuery;
    if (!sqlQuery.exec(SELECT_PAGE)) {
        qWarning() << __func__ << sqlQuery.lastError();
        return itemsIdInHomeScreen;
    }

    while (sqlQuery.next()) {
        int page;
        QString ids;
        std::tie(page, ids) = queryItemDetailsFromPageTable(sqlQuery);
        QStringList sequence = ids.split(',');
        for (int i = 0; i < sequence.size(); ++i) {
            QString itemId = sequence.at(i);
            itemsIdInHomeScreen[page].append(itemId.toInt());
        }
    }
    return itemsIdInHomeScreen;
}

bool DataBase::addAppItem(const UKUI::IconItem &item)
{
    QString placeholder = UKUI::fromQListUIntToString(item.getPlaceHolder());
    QString categories = UKUI::fromQListIntToString(item.getCategories());

    QMap<QString, QVariant> detailsMap = {
        { "itemId", QVariant::fromValue<int>(item.getId()) },
        { "desktopName", QVariant::fromValue<QString>(item.getDesktopName()) },
        { "name", QVariant::fromValue<QString>(item.getName()) },
        { "iconName", QVariant::fromValue<QString>(item.getIconName()) },
        { "type", QVariant::fromValue<int>((int)item.getType()) },
        { "placeholder", QVariant::fromValue<QString>(placeholder) },
        { "categories", QVariant::fromValue<QString>(categories) }
    };

    return addItemToItemList(detailsMap);
}

QVariant DataBase::addWidgetItem(const UKUI::Widget &item)
{
    QString placeholder = UKUI::fromQListUIntToString(item.getPlaceHolder());
    QString categories = "-1";
    QSqlQuery sqlQuery;
    if (!sqlQuery.prepare(QLatin1String(INSERT_ITEMLIST))) {
        qWarning() << __func__ << sqlQuery.lastError().text();
        return QVariant();
    }
    sqlQuery.addBindValue(item.getId());
    sqlQuery.addBindValue(item.getQmlFilePath());
    sqlQuery.addBindValue(item.getName());
    sqlQuery.addBindValue("");
    sqlQuery.addBindValue(static_cast<int>(item.getType()));
    sqlQuery.addBindValue(placeholder);
    sqlQuery.addBindValue(categories);
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << sqlQuery.lastError();
    }
    return sqlQuery.lastInsertId();
}

bool DataBase::addContainerItem(const UKUI::ContainerItem &item, const QList<QList<int>> &itemIdsInContainer)
{
    if (itemIdsInContainer.isEmpty()) {
        qWarning() << "Add container item failed, the item ids in group is empty.";
        return false;
    }
    QString itemSequence = UKUI::fromQListUIntToString(itemIdsInContainer.first());
    for(int i = 1; i < itemIdsInContainer.size(); i++) {
        QList<int> itemIdsInPage = itemIdsInContainer.at(i);
        itemSequence += QString(";") += UKUI::fromQListUIntToString(itemIdsInPage);
    }

    QMap<QString, QVariant> groupDetailsMap = {
        { "setId", QVariant::fromValue<int>(item.getId()) },
        { "sequence", QVariant::fromValue<QString>(itemSequence) },
        { "titleEditable", QVariant::fromValue<bool>(item.isTitleEditable()) },
        { "containerEditable", QVariant::fromValue<bool>(item.isContainerEditable()) },
        { "containerCategory", QVariant::fromValue<QString>(item.getContainerCategory()) },
    };

    if (!addItemToSets(groupDetailsMap)) {
        return false;
    }

    QString placeholder = UKUI::fromQListUIntToString(item.getPlaceHolder());
    QMap<QString, QVariant> itemDetailsMap = {
        { "itemId", QVariant::fromValue<int>(item.getId()) },
        { "desktopName", QVariant::fromValue<QString>("null") },
        { "name", QVariant::fromValue<QString>(item.getName()) },
        { "iconName", QVariant::fromValue<QString>("null") },
        { "type", QVariant::fromValue<int>((int)item.getType()) },
        { "placeholder", QVariant::fromValue<QString>(placeholder) },
        { "categories", QVariant::fromValue<QString>("-1") }
    };

    return addItemToItemList(itemDetailsMap);
}

bool DataBase::updateAppItem(const UKUI::IconItem &item)
{
    QString categories = UKUI::fromQListIntToString(item.getCategories());
    QSqlQuery sqlQuery;
    sqlQuery.prepare(UPDATE_ITEMLIST);
    sqlQuery.addBindValue(item.getDesktopName());
    sqlQuery.addBindValue(item.getName());
    sqlQuery.addBindValue(item.getIconName());
    sqlQuery.addBindValue(categories);
    sqlQuery.addBindValue(item.getId());
    if (!sqlQuery.exec()) {
        qWarning() << "修改应用的数据失败" << __func__ << sqlQuery.lastError();
        return false;
    }
    return true;
}

QVariant DataBase::addGroupItem(const UKUI::GroupItem &item, const QList<QList<int> > &itemIdsInGroup)
{
    if (itemIdsInGroup.isEmpty()) {
        qWarning() << "Add group item failed, the item ids in group is empty.";
        return QVariant();
    }
    QString itemSequence = UKUI::fromQListUIntToString(itemIdsInGroup.first());
    for(int i = 1; i < itemIdsInGroup.size(); i++) {
        QList<int> itemIdsInPage = itemIdsInGroup.at(i);
        itemSequence += QString(";") += UKUI::fromQListUIntToString(itemIdsInPage);
    }

    QMap<QString, QVariant> groupDetailsMap = {
        { "setId", QVariant::fromValue<int>(item.getId()) },
        { "sequence", QVariant::fromValue<QString>(itemSequence) },
        { "titleEditable", QVariant::fromValue<bool>(false) },
        { "containerEditable", QVariant::fromValue<bool>(false) },
        { "containerCategory", QVariant::fromValue<QString>("null") },
    };

    if (!addItemToSets(groupDetailsMap)) {
        return false;
    }

    QMap<QString, QVariant> itemDetailsMap = {
        { "itemId", QVariant::fromValue<int>(item.getId()) },
        { "desktopName", QVariant::fromValue<QString>("null") },
        { "name", QVariant::fromValue<QString>(item.getSourceName()) },
        { "iconName", QVariant::fromValue<QString>("null") },
        { "type", QVariant::fromValue<int>((int)item.getType()) },
        { "placeholder", QVariant::fromValue<QString>("1,1") },
        { "categories", QVariant::fromValue<QString>("-1") }
    };

    return addItemToItemList(itemDetailsMap);
}

bool DataBase::setFlipSetData(quint32 setId, const QList<QList<quint32>> &sequence)
{
    QString itemSequence;
    if(!sequence.isEmpty()) {
        itemSequence += UKUI::fromQListUIntToString(sequence.first());
        for(int i = 1; i < sequence.size(); i++) {
            QList<quint32> setPageItemSeq = sequence.at(i);
            itemSequence += QString(";") += UKUI::fromQListUIntToString(setPageItemSeq);
        }
    }
    qDebug() << __func__ << "itemSequence:" << itemSequence;

    QSqlQuery sqlQuery;
    sqlQuery.prepare(UPDATE_SETS);
    sqlQuery.addBindValue(itemSequence);
    sqlQuery.addBindValue(setId);
    if (!sqlQuery.exec()) {
        qWarning() << "修改flipsets数据失败" << __func__ << __LINE__ << sqlQuery.lastError();
        return false;
    }
    return true;
}

bool DataBase::updateSetData(int setId, const UKUI::ItemIdsPage &itemIdsInPage)
{
    if (itemIdsInPage.isEmpty()) {
        return false;
    }
    QString ids2Database;
    for (int i = 0; i < itemIdsInPage.size(); i++) {
        auto itemIds = itemIdsInPage.at(i);
        ids2Database += UKUI::fromQListUIntToString(itemIds);
        if (i != itemIdsInPage.size() - 1) {
            ids2Database += ";";
        }
    }
    QSqlQuery sqlQuery;
    sqlQuery.prepare(UPDATE_SETS);
    sqlQuery.addBindValue(ids2Database);
    sqlQuery.addBindValue(setId);
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << __LINE__ << sqlQuery.lastError();
        return false;
    }
    return true;
}

bool DataBase::updateSetName(int setId, const QString &name)
{
    if (name.isEmpty())
        return false;
    QSqlQuery sqlQuery;
    sqlQuery.prepare(UPDATE_ITEMLIST_NAME_ITEMID);
    sqlQuery.addBindValue(name);
    sqlQuery.addBindValue(setId);
    if(!sqlQuery.exec()) {
        qDebug() << sqlQuery.lastError();
        return false;
    }
    return true;
}

bool DataBase::addHomeScreenPage(int pageId, const QList<int> &sequence)
{
    return updateHomeScreenPageTable(pageId, sequence, INSERT_PAGE);
}

bool DataBase::deleteHomeScreenPage(int pageId)
{
    if (pageId < 0) {
        qDebug() << __func__ << "param id error" << pageId;
        return false;
    }
    if (!isTableExist("page")) {
        qDebug() << __func__ << "page table is not exits";
        return false;
    }
    QSqlQuery sqlQuery;
    if (!sqlQuery.exec(QString(DELETE_PAGE_BY_PAGEID).arg(pageId))) {
        qWarning() << __func__ << sqlQuery.lastError();
        return false;
    }
    return true;
}

bool DataBase::updateHomeScreenPage(int pageId, const QList<int> &sequence)
{
    return updateHomeScreenPageTable(pageId, sequence, UPDATE_PAGE);
}

bool DataBase::setPageData(quint32 pageId, const QList<quint32> &sequence)
{
    qDebug() << "pre setPageData";
    QString itemSequence = UKUI::fromQListUIntToString(sequence);
    QSqlQuery sqlQuery;
    sqlQuery.prepare(UPDATE_PAGE);
    sqlQuery.addBindValue(itemSequence);
    sqlQuery.addBindValue(pageId);
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << __LINE__ << sqlQuery.lastError();
        return false;
    }
    return true;
}

bool DataBase::setPageData(int pageId, const QList<int> &sequence)
{
    QString itemSequence = UKUI::fromQListUIntToString(sequence);
    QSqlQuery sqlQuery;
    sqlQuery.prepare(UPDATE_PAGE);
    sqlQuery.addBindValue(itemSequence);
    sqlQuery.addBindValue(pageId);
    qDebug() << __FUNCTION__ << pageId << itemSequence << sqlQuery.exec();
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << __LINE__ << sqlQuery.lastError();
        return false;
    }
    return true;
}

bool DataBase::deleteItemListData(int id)
{
    if (isTableExist("itemlist")) {
        QSqlQuery sqlQuery;
        if (!sqlQuery.exec(QString(DELETE_ITEMLIST_BY_ITEMID).arg(id))) {
            qWarning() << "从列表中删除应用失败" << __func__ << sqlQuery.lastError();
            return false;
        }
        qDebug() << "Delete ItemList Data success ! ! !" << "Id:" << id;
    }
    return true;
}

bool DataBase::deletePageData(int id)
{
    if (id < 0) {
        qDebug() << __func__ << "param id error" << id;
        return false;
    }
    if (!isTableExist("page")) {
        qDebug() << __func__ << "page table is not exits";
        return false;
    }
    QSqlQuery sqlQuery;
    if (!sqlQuery.exec(QString(DELETE_PAGE_BY_PAGEID).arg(id))) {
        qWarning() << __func__ << sqlQuery.lastError();
        return false;
    }
    qDebug() << "Delete Page Data success ! ! !" << "PageId:" << id;
    return true;
}

bool DataBase::queryItemIdFromList(int itemId)
{
    QString sql = SELECT_ITEMLIST_BY_ITEMID;
    QSqlQuery sqlQuery;
    sqlQuery.prepare(sql);
    sqlQuery.bindValue(":itemId", itemId);
    if (!sqlQuery.exec()) {
        qWarning() << __func__ << __LINE__ << sqlQuery.lastError();
        return false;
    }
    if (!sqlQuery.last()) {
        qDebug()<<"lili____sqlQuery.last()"<<sqlQuery.last()<<itemId;
        return false;
    }
    return true;
}

bool DataBase::queryPageItemIdFromSet(int itemId)
{
    QSqlQuery sqlQuery;
    sqlQuery.exec(SELECT_SETS);
    if(!sqlQuery.exec()) {
        qWarning() << __func__ << sqlQuery.lastError();
        return false;
    }
    while(sqlQuery.next()) {
        if (sqlQuery.value(3).toInt() == 0) {
            QStringList flipSet = sqlQuery.value(2).toString().split(';');
            for (int i = 0; i < flipSet.size(); ++i) {
                QStringList setPageItem = flipSet.at(i).split(",");
                for (int j = 0; j < setPageItem.size(); ++j) {
                    if (setPageItem.at(j).toInt() == itemId) {
                        return true;
                    }
                }
            }
        }
        else if(sqlQuery.value(3).toInt() == 1) {
            QStringList scrollSet = sqlQuery.value(2).toString().split(",");
            for (int i = 0; i < scrollSet.size(); ++i) {
                QStringList setPageItem = scrollSet.at(i).split(",");
                for (int j = 0; j < setPageItem.size(); ++j) {
                    if (setPageItem.at(j).toInt() == itemId) {
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

bool DataBase::deleteSet(int setId)
{
    if (!isTableExist("sets")) {
        qWarning() << "sets table is not exits" << __func__;
        return false;
    }
    QSqlQuery sqlQuery;
    if (!sqlQuery.exec(QString(DELETE_SETS_BY_SETID).arg(setId))) {
        qWarning() << __func__ << sqlQuery.lastError();
        return false;
    }
    return deleteItemListData(setId);
}

bool DataBase::deleteTableAllData(const QString &tableName)
{
    if (!isTableExist(tableName)) {
        return false;
    }
    QSqlQuery sqlQuery;
    if(!sqlQuery.exec(QString(DELETE_TABLEDATA_BY_TABLENAME).arg(tableName))) {
        qDebug() << sqlQuery.lastError();
        return false;
    }
    qDebug() << "Delete Table All Data success ! ! !";
    return true;
}

bool DataBase::checkTables()
{
    QSqlQuery sqlQuery;
    if (!isTableExist("itemlist")) {
        firstInit = true;
        if (!sqlQuery.exec(QLatin1String(CREATE_TABLE_ITEMLIST))) {
            qWarning() << __func__ << sqlQuery.lastError().text();
            return false;
        }
        createItemsData();

        if (!isTableExist("sets")) {
            if (!sqlQuery.exec(QLatin1String(CREATE_TABLE_SETS))) {
                qWarning() << __func__ << sqlQuery.lastError().text();
                return false;
            }
        } else {
            if (!deleteTableAllData("sets")) {
                qWarning() << __func__ << "删除set表数据失败";
                return false;
            }
        }

        if (!isTableExist("page")) {
            if (!sqlQuery.exec(QLatin1String(CREATE_TABLE_PAGE))) {
                qWarning() << __func__ << sqlQuery.lastError().text();
                return false;
            }
        } else {
            if (!deleteTableAllData("page") ) {
                qWarning() << __func__ << "删除page表数据失败";
                return false;
            }
        }
    } else {
        if (isTableExist("sets") && isTableExist("page")) {
            checkSetsTableFields();
            return true;
        } else {
            qDebug() << isTableExist("sets") << isTableExist("page");
            if (!isTableExist("sets")) {
                if (!sqlQuery.exec(QLatin1String(CREATE_TABLE_SETS))) {
                    qWarning() << __func__ << sqlQuery.lastError().text();
                    return false;
                }
            } else {
                if (!deleteTableAllData("sets")) {
                    qWarning() << __func__ << "删除set表数据失败";
                    return false;
                }
            }

            if (!isTableExist("page")) {
                firstInit = true;
                if (!sqlQuery.exec(QLatin1String(CREATE_TABLE_PAGE))) {
                    qWarning() << __func__ << sqlQuery.lastError().text();
                    return false;
                }
            } else {
                if (!deleteTableAllData("page") ) {
                    qWarning() << __func__ << "删除page表数据失败";
                    return false;
                }
            }
        }
    }
    return true;
}

bool DataBase::firstInited()
{
    return firstInit;
}

void DataBase::closeDataBase()
{
    db.close();
}
